import org.junit.Assert;
import org.junit.Test;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

public class testString {


    @Test
    public void chatAtTest() {
        //index begin zero,can`t out of bounds
        String string = "hello world";
        System.out.println(string.charAt(10));// d
        System.out.println(string.charAt(5));// space
        System.out.println(string.charAt(6));// w
        System.out.println(string.charAt(0));// h
        //System.out.println(string.charAt(20));//StringIndexOutOfBoundsException
    }

    @Test
    public void codePointTest() {
        //Unicode，全称为Unicode标准（The Unicode Standard）
        // 其官方机构Unicode联盟所用的中文名称为统一码
        String string = "hello world";
        System.out.println(string.codePointAt(10));//d->100
        System.out.println(string.codePointBefore(10));//l->108
        //如果字符串可能包含 特殊 Unicode 字符（emoji、日文汉字、音乐符号等）
        // 请使用 codePointCount() 计算 Unicode 代码点数量，否则 length() 可能 误判字符个数
        //普通字符（BMP 范围内 U+0000 ~ U+FFFF） 计为 1 个代码点。
        //扩展字符（超出 BMP，如 emoji 和特殊符号） 计为 1 个代码点，但 占用 2 个 char
        System.out.println(string.codePointCount(0, 10));//codePointCount(0, 10) 计算的字符范围是 "hello worl"（不包含最后的 "d"）
        System.out.println(string.codePointCount(0, 11));
    }

    @Test
    public void compareToTest() {
        // compareTo
        String stringA = "hello world";//11 char
        String stringB = "love you xhl";//12 char different length and the first not same
        System.out.println(stringA.compareTo(stringB));//-4
        // 字符 'h' 的 Unicode 值是 104，字符 'l' 的 Unicode 值是 108。
        //由于 'h' < 'l'，因此 stringA 会小于 stringB，compareTo 返回负值
        String stringC = "qwer";
        String stringD = "qwe";//different length
        System.out.println(stringC.compareTo(stringD));//-1
        System.out.println(stringD.compareTo(stringC));//1
        System.out.println(stringD.compareTo(stringD));//0
        String stringE = "qwer";
        String stringF = "qwel";//the same length
        System.out.println(stringE.compareTo(stringF));//6


        //compareToIgnoreCase  //can`t  check A or a
        String stringG = "qwEr";
        String stringH = "Qwer";
        System.out.println(stringG.compareToIgnoreCase(stringH));
    }

    @Test
    public void concatTest() {
        String string = "love you";
        String str = string.concat(" my baby");//不是对原字符串进行拼接，而是产生新的字符串
        System.out.println(string);// output love you
        System.out.println(str);// output love you my baby
    }

    @Test
    public void containsTest() {
        //contains
        String string = "love you";
        boolean resultA = string.contains("you");
        boolean resultC = string.contains("y");
        boolean resultB = string.contains("my");
        System.out.println(resultA);
        System.out.println(resultB);
        System.out.println(resultC);

    }

    @Test
    public void contentEqualsTest() {
        String string = "love you";
        //contentEquals
        CharSequence string1 = "my";
        StringBuilder string2 = new StringBuilder("love you");
        System.out.println(string.contentEquals(string1));
        System.out.println(string.contentEquals(string2));
    }

    @Test
    public void copyValueOfTest() {
        char[] chars = {'h', 'e', 'l', 'l', 'o'};
        String string = String.copyValueOf(chars);
        System.out.println(string);
        String string1 = String.copyValueOf(chars, 1, 2);//从哪里开始，往后
        System.out.println(string1);
    }

    @Test
    public void endsWithTest() {//判断是否以给定字符串结尾
        String string = "hello world";
        System.out.println(string.endsWith("l"));
        System.out.println(string.endsWith("world"));
        System.out.println(string.endsWith(" world"));
        System.out.println(string.endsWith("d"));
    }

    @Test
    public void equalsTest() {
        //equals
        String string = "hello world";
        System.out.println(string.equals("world"));
        System.out.println(string.equals(new String("hello world")));
        System.out.println(string.equals(new String("hEllo world")));
        //equalsIgnoreCase
        System.out.println(string.equalsIgnoreCase("hello woRld"));
        System.out.println(string.equalsIgnoreCase(new String("helLo world")));
    }

    @Test
    public void formatTest() {
        //format(String format, Object... args)//类似于c语言里的输出
        int num = 3;
        System.out.println(String.format("hello! %s i love you %d thousands", "xhl, ", num));
        //format(Locale l, String format, Object... args)//带地区的
        //not display
        //formatted(Object... args)
        //与format作用一样，只不过这个可以后来给，而上面只能调用
        String string = "hello! %s i love you %d thousands";
        String result = string.formatted("xhl", num);//不能直接替换字符串，需要生成新的字符串
        System.out.println(string);
        System.out.println(result);
        System.out.println(result.formatted("cx", 1));


    }

    @Test
    public void getBytesTest() throws UnsupportedEncodingException {
        String string = "hello world";
        byte[] bytes = string.getBytes();//把字符串改为字节码输出
        for (byte aByte : bytes) {
            System.out.println(aByte);
        }
        byte[] utf8Bytes = string.getBytes("UTF-8");
        byte[] gbkBytes = string.getBytes(Charset.forName("GBK"));
    }

    @Test
    public void getCharsTest() {
        String string = "hello world";
        char[] chars = new char[20];
        string.getChars(0, 10, chars, 4);//要给定字符数组，但是要创建空的，就需要new出来
        for (char aChar : chars) {
            System.out.println(aChar);
        }
    }

    @Test
    public void hashCodeTest() {
        String string = "hello world";//返回字符串的hashCode
        System.out.println(string.hashCode());
    }

    @Test
    public void indentTest() {
        String string = "i\nlove\ryou";
        System.out.println(string.indent(2));
    }

    @Test
    public void indexOfTest() {
        String string = "hello world";
        System.out.println(string.indexOf("l"));
        System.out.println(string.indexOf("l", 3));
        System.out.println(string.indexOf("l", 5, 10));
        System.out.println(string.indexOf("ll"));//返回的是字符串第一个字符的下标
        System.out.println(string.indexOf("ll", 6));//找不到返回-1
        System.out.println(string.indexOf("ld", 5, 11));
    }

    @Test
    public void internTest() {
        //intern() 的作用
        //减少内存占用：避免存储重复的字符串，提高效率。
        //加快字符串比较：使用 == 进行比较时更快（因为指向相同的引用）
        //
        //直接赋值字符串，是存储在字符串串池中，而new出来的字符串是堆上的对象
        // intern的目的就是使字符串堆上的对象，去与串池中的字符串进行比较，指向串池
        String string = "i love you";
        String string1 = new String("i love you");
        String string2 = new String("i lobe ") + new String("you");
        System.out.println(string1 == string);//string1在堆上，string是在字符串串池中
        System.out.println(string1.intern() == string);//string1指向字符串串池了，string是在字符串串池中
        System.out.println(string1.intern() == string2);//string1指向字符串串池了，string2还是是堆上的对象

    }

    @Test
    public void isBlankADNisEmptyTest() {

        String string = "";
        String string1 = " ";
        String string2 = "\n";
        //isBlank//如果字符串为空或仅包含空格代码点，则返回true，否则返回false
        System.out.println(string.isBlank());
        System.out.println(string1.isBlank());
        System.out.println(string2.isBlank());
        //isEmpty
        System.out.println(string.isEmpty());
        System.out.println(string1.isEmpty());
        System.out.println(string2.isEmpty());

    }

    @Test
    public void linesTest() {
        //在 String.lines() 方法中，\r 也被视为换行符
        // 因为 lines() 方法会自动按照 "行终止符" 进行拆分
        // 而行终止符不仅包括 \n，还包括 \r 或 \r\n
        String string = "i love you\ni very love you\rxhl";
        Stream<String> lines = string.lines();
        lines.forEach(System.out::println);
    }

    @Test
    public void matchesTest() {
        String string = "11qq";
        System.out.println(string.matches("\\d+"));//必须纯数字才能返回true
    }

    @Test
    /*对解决unicode表情等占俩个代码点，使正确获取之后字符串的下标*/
    public void offsetByCodePointsTest() {
        String string = "i love you";
        System.out.println(string.offsetByCodePoints(0, 2));
    }

    @Test
    /*比较两个字符串其中一小部分是否相等，也可以忽略大小写比较*/
    public void regionMatchesTest() {
        String string01 = "hello world";
        String string02 = "hello World i love";
        System.out.println(string01.regionMatches(6, string02, 6, 5));
        System.out.println(string01.regionMatches(true, 6, string02, 6, 5));//忽略大小写

    }

    @Test
    /*重复字符串返回字符串多少次*/
    public void repeatTest() {
        String string = " i love you ";
        System.out.println(string.repeat(3));
    }

    @Test
    /*replace，replaceAll，replaceFirst，替换指定字符,替换指定字符串,指定只替换第一个*/
    public void replaceTest() {
        String oldStr = "hello world,hello world,hello world";
        System.out.println(oldStr.replace("l", "M"));
        System.out.println(oldStr.replace("hello", "hi"));
        System.out.println(oldStr.replace("ll", "QQ"));
        System.out.println(oldStr.replace("llo w", "QQ"));
        System.out.println("=========================================");
        System.out.println(oldStr.replaceAll("hello", "hi"));
        System.out.println(oldStr.replaceFirst("hello", "hi"));

    }

    @Test
    /*按需求分割字符串,去掉分隔符和带上分隔符的*/
    public void splitTest() {
        String oldStr = "i,,,love,you";
        String[] newStr1 = oldStr.split(",");
        for (int i = 0; i < newStr1.length; i++) {
            System.out.println(newStr1[i]);
        }
        String[] newStr2 = oldStr.split(",",-1);
        System.out.println("===================");
        for (int i = 0; i < newStr2.length; i++) {
            System.out.println(newStr2[i]);
        }
        String[] newStr3 = oldStr.splitWithDelimiters(",",-1);
        System.out.println("===================");
        for (int i = 0; i < newStr3.length; i++) {
            System.out.println(newStr3[i]);
        }
    }
}
